﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Serialization;
using ASRSubsDownloader.FileHelper;
using Microsoft.Win32;
using File = System.IO.File;

namespace ASRSubsDownloader.Common
{
    public static class Config
    {
        public static string BaseFolder { get; set; }

        public static string Language { get; set; }

        public static bool AutoRun { get; set; }

        public static string SecurityToken { get; set; }

        private static string[] _FileExtensions;

        public static string[] FileExtensions
        {
            get { return _FileExtensions; }
            set
            {
                for (int idx = 0; idx < value.Count(); idx++)
                {
                    value[idx] = value[idx].Trim(' ');
                }
                _FileExtensions = value;
            }
            
        }

        public static FileCache FilesCache { get; set; }

        public static FileCache BlackList { get; set; }

        public static string _fileExtensions
        {
            get 
            { 
                return FileExtensions == null ? "" : FileExtensions.Aggregate("", (current, fileExtension) => current + (fileExtension + ",")).TrimEnd(',');
            }
        }

        public static string OpenSubtitlesUserName { get; set; }

        public static string OpenSubtitlesPassword { get; set; }

        public const string OpenSubtitlesUserAgent = "OpenSubsAPI";
        
        public static List<Language> Languages { get; set; }

        public static void LoadConfig()
        {
            StreamReader strReader = null;
            var fl = File.Open(Application.StartupPath + "\\Languages.xml", FileMode.Open);
            Languages = new List<Language>();
            var serializer = new XmlSerializer(Languages.GetType());
            Languages = (List<Language>) serializer.Deserialize(fl);
            fl.Close();
            if(!File.Exists(Application.StartupPath + "\\config.txt"))
            {
                var frm = new Forms.ConfigForm();
                frm.Show("Por favor, preencha as configurações necessárias");
            }
            try
            {
                fl = File.Open(Application.StartupPath + "\\config.txt", FileMode.Open);
                strReader = new StreamReader(fl);
                Language = strReader.ReadLine();
                BaseFolder = strReader.ReadLine();
                FileExtensions = strReader.ReadLine().Split(',');
                for (int idx = 0; idx < FileExtensions.Count(); idx++)
                {
                    FileExtensions[idx] = FileExtensions[idx].Trim(' ');
                }

                OpenSubtitlesUserName = strReader.ReadLine();
                OpenSubtitlesPassword = strReader.ReadLine();
                strReader.Close();
                fl.Close();
                

            }
            catch (Exception)
            {
                try
                {
                    fl.Close();
                }
                catch
                {
                }
                try
                {
                    if (strReader != null)
                        strReader.Close();
                }
                catch
                {
                } 
                var frm = new Forms.ConfigForm();
                frm.Show("Arquivo de configuração corrompido, por favor, preencha as informações novamente");
                LoadConfig();
            }
            FileStream f= null;
            try
            {
                FilesCache = new FileCache();
                var x = new XmlSerializer(FilesCache.GetType());
                f = File.Open(Application.StartupPath + "\\FilesCache.xml", FileMode.Open);
                FilesCache = (FileCache) x.Deserialize(f);
                f.Close();
            }
            catch
            {
                try
                {
                    f.Close();
                }
                catch
                {
                }
                FillFileCache();
            }
            f = null;
            try
            {
                BlackList = new FileCache();
                var x = new XmlSerializer(BlackList.GetType());
                f = File.Open(Application.StartupPath + "\\BlackList.xml", FileMode.Open);
                BlackList = (FileCache)x.Deserialize(f);
                f.Close();
            }
            catch
            {
                try
                {
                    f.Close();
                }
                catch
                {
                }
                CreateBlackList();
            }
            RegistryKey add = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
            AutoRun = (add.GetValue("ASRSubtitlesDownloader", null) != null);
            if (BlackList != null && BlackList.Files != null && BlackList.Files.Any())
                FilesCache.Files.RemoveAll(x => BlackList.Files.Any(y => y.FileName == x.FileName));
        }

        public static void FillFileCache()
        {
            FilesCache = new FileCache();
            FilesCache.Files = GetMovieFiles(Config.BaseFolder);
            var f = File.Open(Application.StartupPath + "\\FilesCache.xml", FileMode.OpenOrCreate);
            var x = new XmlSerializer(FilesCache.GetType());
            x.Serialize(f, FilesCache);
            f.Close();
            if (BlackList != null && BlackList.Files != null && BlackList.Files.Any())
                FilesCache.Files.RemoveAll(w => BlackList.Files.Any(y => w.FileName == y.FileName));

        }

        public static void CleanBlackList()
        {
            BlackList.Files.ForEach(x =>
                                    {
                                        var file = new FileHelper.File();
                                        file.FileName = x.FileName;
                                        file.HasSubtitle = File.Exists(x.FileName.GetFileNameWithOutExtension() + ".srt");
                                        FilesCache.Files.Add(file);
                                    });
            BlackList.Files.Clear();
        }

        public static void CreateBlackList()
        {
            BlackList = new FileCache();
            BlackList.Files = new List<FileHelper.File>();
            var f = File.Open(Application.StartupPath + "\\BlackList.xml", FileMode.OpenOrCreate);
            var x = new XmlSerializer(BlackList.GetType());
            x.Serialize(f, BlackList);
            f.Close();
        }

        private static List<FileHelper.File> GetMovieFiles(string directory)
        {
            var list = new List<FileHelper.File>();
            foreach (string str in Directory.GetFiles(directory))
            {
                if (Config.FileExtensions.Any(x => x.ToLower() == str.GetFileExtension().ToLower()))
                {
                    var file = new FileHelper.File();
                    file.FileName = str;
                    file.HasSubtitle = File.Exists(str.GetFileNameWithOutExtension() + ".srt");
                    list.Add(file);
                }
            }
            foreach (string str2 in Directory.GetDirectories(directory))
            {
                list.AddRange(GetMovieFiles(str2));
            }
            return list;
        }

        public static void SaveConfig()
        {
            if(File.Exists(Application.StartupPath + "\\config.txt"))
                File.Delete(Application.StartupPath + "\\config.txt");
            var fl = File.Create(Application.StartupPath + "\\config.txt");
            var strWriter = new StreamWriter(fl);
            strWriter.WriteLine(Language);
            strWriter.WriteLine(BaseFolder);
            strWriter.WriteLine(_fileExtensions);
            strWriter.Close();
            fl.Close();
            try
            {
                if (AutoRun)
                {
                    RegistryKey add = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                    if (add.GetValue("ASRSubtitlesDownloader", null) == null)
                        add.SetValue("ASRSubtitlesDownloader", "\"" + Application.ExecutablePath.ToString() + "\"");
                }
                else
                {
                    RegistryKey add = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                    if (add.GetValue("ASRSubtitlesDownloader", null) != null)
                        add.DeleteValue("ASRSubtitlesDownloader");
                }
            }
            catch 
            {
            }
        }

    }

    public class Language
    {
        public Language():this("","")
        {
        }

        public string Code { get; set; }
        public string Name { get; set; }
        public Language(string code, string name)
        {
            Code = code;
            Name = name;
        }
    }
}
